import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.BufferedReader;
import java.io.FileReader;

/**
 * 形状接口
 */
interface Shape {
    public double perimeter(); // 计算形状的周长
    public double area(); // 计算形状的面积
}

/**
 * 参数为负数异常类
 */
class NegativeException extends RuntimeException {
    public NegativeException(String message) {
        super(message);
    }
}

/**
 * 圆型类
 */
class Circle implements Shape {
    private double radius;

    public Circle(double radius) throws NegativeException {
        if (radius < 0) {
            throw new NegativeException("半径为负数");
        }
        this.radius = radius;
    }

    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }

    @Override
    public double area() {
        return Math.PI * Math.pow(radius, 2);
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}

/**
 * 正方形类
 */
class Square implements Shape {
    private double width;

    public Square(double width) throws NegativeException {
        if (width < 0) {
            throw new NegativeException("边长为负数");
        }
        this.width = width;
    }

    @Override
    public double perimeter() {
        return 4 * width;
    }

    @Override
    public double area() {
        return width * width;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }
}

/**
 * 三角形三边不合法异常类
 */
class InvalidTriangleException extends RuntimeException {
    public InvalidTriangleException(String message) {
        super(message);
    }
}

/**
 * 三角形类
 */
class Triangle implements Shape {
    private double side1;
    private double side2;
    private double side3;

    public Triangle(double side1, double side2, double side3) throws InvalidTriangleException, NegativeException {
        if (side1 < 0 || side2 < 0 || side3 < 0) {
            throw new NegativeException("三角形边长为负数");
        }
        if (side1 + side2 <= side3 || side1 + side3 <= side2 || side2 + side3 <= side1) {
            throw new InvalidTriangleException("三角形三边长度不合法");
        }
        this.side1 = side1;
        this.side2 = side2;
        this.side3 = side3;
    }

    @Override
    public double perimeter() {
        return side1 + side2 + side3;
    }

    @Override
    public double area() {
        double p = perimeter() / 2;
        return Math.sqrt(p * (p - side1) * (p - side2) * (p - side3));
    }

    public double getSide1() {
        return side1;
    }

    public void setSide1(double side1) {
        this.side1 = side1;
    }

    public double getSide2() {
        return side2;
    }

    public void setSide2(double side2) {
        this.side2 = side2;
    }

    public double getSide3() {
        return side3;
    }

    public void setSide3(double side3) {
        this.side3 = side3;
    }
}

/**
 * 矩形类
 */
class Rectangle extends Square {
    private double height;

    public Rectangle(double width, double height) throws NegativeException {
        super(width);
        if (width < 0 || height < 0) {
            throw new NegativeException("矩形边长为负数");
        }
        this.height = height;
    }

    @Override
    public double perimeter() {
        return 2 * getWidth() + 2 * height;
    }

    @Override
    public double area() {
        return getWidth() * height;
    }

    public double getWidth() {
        return super.getWidth();
    }

    public void setWidth(double width) {
        super.setWidth(width);
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
}

/**
 * 椭圆型类
 */
class Ellipse extends Circle {
    private double semiMajorAxis;

    public Ellipse(double semiMinorAxis, double semiMajorAxis) throws NegativeException {
        super(semiMinorAxis);
        if (semiMinorAxis < 0 || semiMajorAxis < 0) {
            throw new NegativeException("椭圆半轴长为负数");
        }
        this.semiMajorAxis = semiMajorAxis;
    }

    @Override
    public double perimeter() {
        return Math.PI * Math.sqrt(2 * (getSemiMinorAxis() * getSemiMinorAxis() + semiMajorAxis * semiMajorAxis));
    }

    @Override
    public double area() {
        return Math.PI * getSemiMinorAxis() * semiMajorAxis;
    }

    public double getSemiMinorAxis() {
        return getRadius();
    }

    public void setSemiMinorAxis(double semiMinorAxis) {
        setRadius(semiMinorAxis);
    }

    public double getSemiMajorAxis() {
        return semiMajorAxis;
    }

    public void setSemiMajorAxis(double semiMajorAxis) {
        this.semiMajorAxis = semiMajorAxis;
    }
}


public class HW2 {
    public static void javaClassInterface() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入第1个浮点数: ");
        double value1 = 0;
        try {
            value1 = scanner.nextDouble();
        } catch (InputMismatchException e) {
            System.out.println(e.getMessage());
        }

        System.out.print("请输入第2个浮点数: ");
        double value2 = 0;
        try {
            value2 = scanner.nextDouble();
        } catch (InputMismatchException e) {
            System.out.println(e.getMessage());
        }

        System.out.print("请输入第3个浮点数: ");
        double value3 = 0;
        try {
            value3 = scanner.nextDouble();
        } catch (InputMismatchException e) {
            System.out.println(e.getMessage());
        }

        try {
            Circle circle = new Circle(value1);
            System.out.printf("圆半径：%.2f\n", circle.getRadius());
            System.out.printf("圆周长：%.2f\n", circle.perimeter());
            System.out.printf("圆面积：%.2f\n", circle.area());
        } catch (NegativeException e) {
            System.out.println(e.getMessage());
        }

        try {
            Square square = new Square(value1);
            System.out.printf("正方形边长：%.2f\n", square.getWidth());
            System.out.printf("正方形周长：%.2f\n", square.perimeter());
            System.out.printf("正方形面积：%.2f\n", square.area());
        } catch (NegativeException e) {
            System.out.println(e.getMessage());
        }

        try {
            Triangle triangle = new Triangle(value1, value2, value3);
            System.out.printf("三角形三边长：%.2f, %.2f, %.2f\n", triangle.getSide1(), triangle.getSide2(), triangle.getSide3());
            System.out.printf("三角形周长：%.2f\n", triangle.perimeter());
            System.out.printf("三角形面积：%.2f\n", triangle.area());
        } catch (InvalidTriangleException | NegativeException e) {
            System.out.println(e.getMessage());
        }

        try {
            Rectangle rectangle = new Rectangle(value1, value2);
            System.out.printf("矩形长、宽：%.2f, %.2f\n", rectangle.getHeight(), rectangle.getWidth());
            System.out.printf("矩形周长：%.2f\n", rectangle.perimeter());
            System.out.printf("矩形面积：%.2f\n", rectangle.area());
        } catch (NegativeException e) {
            System.out.println(e.getMessage());
        }

        try {
            Ellipse ellipse = new Ellipse(value1, value2);
            System.out.printf("椭圆短半轴、长半轴：%.2f, %.2f\n", ellipse.getSemiMinorAxis(), ellipse.getSemiMajorAxis());
            System.out.printf("椭圆近似周长：%.2f\n", ellipse.perimeter());
            System.out.printf("椭圆面积：%.2f\n", ellipse.area());
        } catch (NegativeException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void wordFrequencyStatistics() {
        LinkedHashMap<String, Integer> wordFrequencyMap = new LinkedHashMap<>();

        try (BufferedReader bufferedReader = new BufferedReader(new FileReader("src/text.txt"))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                ArrayList<String> words = extractWords(line);

                for (String word : words) {
                    String lowerCaseWord = word.toLowerCase();
                    if (!wordFrequencyMap.containsKey(lowerCaseWord)) {
                        wordFrequencyMap.put(lowerCaseWord, 0);
                    }
                    wordFrequencyMap.replace(
                            lowerCaseWord,
                            wordFrequencyMap.get(lowerCaseWord),
                            wordFrequencyMap.get(lowerCaseWord) + 1
                    );
                }
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }

        ArrayList<Map.Entry<String, Integer>> entryList = new ArrayList<>(wordFrequencyMap.entrySet());
        entryList.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));

        wordFrequencyMap.clear();
        for (int i = 0; i < 5; i++) {
            Map.Entry<String, Integer> entry = entryList.get(i);
            wordFrequencyMap.put(entry.getKey(), entry.getValue());
        }
        System.out.println(wordFrequencyMap);
    }

    public static void main(String[] args) {
        javaClassInterface();
        wordFrequencyStatistics();
    }

    public static ArrayList<String> extractWords(String text) {
        ArrayList<String> words = new ArrayList<>();
        // 匹配字母和撇号的组合（允许单词中间有“'”）
        Pattern pattern = Pattern.compile("[a-zA-Z']+");
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            String word = matcher.group();
            // 清理单词前后的非字母字符（如标点）
            word = word.replaceAll("^[^a-zA-Z]+", "");  // 去除开头非字母
            word = word.replaceAll("[^a-zA-Z]+$", "");  // 去除结尾非字母
            if (!word.isEmpty()) {
                words.add(word);
            }
        }

        return words;
    }
}
